<!-- 富文本编辑器组件 -->
<!-- props           | type   | required | default | value | 说明 -->
<!-- default-content | String | false    | []      | -     | 编辑器缺省内容 -->
<!-- height          | String | false    | 500px   | -     | 编辑器高度 -->
<!-- emits          | 说明 -->
<!-- content-change | 编辑器内容变化后的回调 -->
<script setup lang="ts">
import { onBeforeUnmount, ref, shallowRef, computed, watch } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import cloneDeep from 'lodash.clonedeep'
import useEditorTool from '../../hooks/useEditorTool'
import type { IEditorConfig, IToolbarConfig } from '@wangeditor/editor'
import { uploadFile } from '@/utils/uploader'
import { ElMessage } from 'element-plus'

const props = defineProps({
  defaultContent: {
    type: String,
    default: '[]'
  },
  height: {
    type: String,
    default: '460px'
  }
})

const emit = defineEmits(['content-change'])

const { formatImage } = useEditorTool()

const editorHeight = ref(props.height)

watch(
  () => props.height,
  (newVal) => {
    editorHeight.value = newVal
  }
)

const fullscreenLoading = ref(false)

// 编辑器实例，必须用 shallowRef，重要！
const editorRef = shallowRef()

// 编辑将默认显示的内容
const getDefaultContent = computed(() => {
  const arr = JSON.parse(props.defaultContent)
  return cloneDeep(arr)
}) // 注意，深拷贝

// 工具栏配置
// group-image: 上传图片图标
const toolbarConfig: Partial<IToolbarConfig> = {
  excludeKeys: ['insertVideo', 'insertLink', 'emotion', 'todo', 'codeBlock', 'group-video', 'blockquote']
}

// 编辑器配置
const editorConfig: Partial<IEditorConfig> = {
  placeholder: '请输入内容...',
  MENU_CONF: {
    uploadImage: {
      customUpload(file: any, insertFn: any) {
        fullscreenLoading.value = true
        uploadFile({ file })
          .then((res: any) => {
            insertFn(res.url)
          })
          .catch((err: any) => {
            ElMessage({
              type: 'error',
              message: err.msg
            })
          })
          .finally(() => {
            fullscreenLoading.value = false
          })
      }
    },
    uploadVideo: {
      customUpload(file: any, insertFn: any) {
        fullscreenLoading.value = true
        uploadFile({ file })
          .then((res: any) => {
            let url = res.url
            if (res.url.indexOf('http') < 0) {
              url = `http://${res.url}`
            }
            insertFn(url)
          })
          .finally(() => {
            fullscreenLoading.value = false
          })
      }
    }
  }
}

// 编辑器回调函数 - 创建成功
const handleCreated = (editor: any) => {
  editorRef.value = editor // 记录 editor 实例，重要！
}

// 编辑器回调函数 - 内容变化
const handleChange = (editor: any) => {
  // 获取回显content
  const contentStr = JSON.stringify(editor.children)
  // 获取html
  const html = editor.getHtml()
  // 获取摘要信息
  // const text = editor.getText().replace(/\n/g, '').trim().replace(/ /g, '').substring(0, 30)
  console.log(contentStr)
  console.log(html)
  emit('content-change', contentStr, html)
}

defineExpose({
  formatImage
})

// 组件销毁时，也及时销毁编辑器，重要！
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor) {
    editor.destroy()
  }
})
</script>

<template>
  <div v-loading.fullscreen.lock="fullscreenLoading" class="custom-editor-wrapper" element-loading-text="上传中...">
    <!-- 工具栏 -->
    <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :default-config="toolbarConfig" />
    <!-- 编辑器 -->
    <Editor
      style="overflow-y: hidden"
      :style="{ height: editorHeight }"
      :default-config="editorConfig"
      :default-content="getDefaultContent"
      @on-created="handleCreated"
      @on-change="handleChange"
    />
  </div>
</template>

<!-- 别忘了引入样式 -->
<style src="@wangeditor/editor/dist/css/style.css"></style>

<style lang="scss" scoped>
.custom-editor-wrapper {
  overflow: auto;
  border: 1px solid #cccccc;
}
</style>
